package xin.nick;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson2.JSON;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author Nick
 * @since 2023/6/29
 */
public class LuceneDemo {

    static String indexPath = "my/index";

    public static void main(String[] args) throws IOException, ParseException {
//        createIndex();
        searchIndex();
    }

    /**
     * 创建索引
     * @throws IOException
     */
    private static void createIndex() throws IOException {

        // 索引文件位置
        File indexFile = new File(indexPath);
        if (!indexFile.exists()) {
            indexFile.mkdirs();
        }

        // 中文分词
        SmartChineseAnalyzer standardAnalyzer = new SmartChineseAnalyzer();

        // 1. 指定索引库位置
        Directory directory = FSDirectory.open(new File(indexPath).toPath());

        // 2. 创建 IndexWriterConfig 对象
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(standardAnalyzer);

        // 3. 创建 IndexWriter 对象
        IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig);

        // 4. 获取原始文档信息
        File file = new File("C:\\m\\诗经.txt");
        List<String> contentList = FileUtil.readUtf8Lines(file);

        for (String content : contentList) {
            // 5. 创建 Field 域, 第一个参数：域的名称, 第二个参数：域的内容, 第三个参数：是否存储
            Field fileContentField = new TextField("content", content, Field.Store.YES);

            // 6. 创建 Document 文档, 存入 Field 域
            Document document = new Document();
            document.add(fileContentField);

            // 7. 创建索引并写入索引库
            indexWriter.addDocument(document);
        }

        // 8. 释放资源
        indexWriter.close();
    }

    /**
     * 搜索
     */
    private static void searchIndex() throws ParseException, IOException {
        long start = System.currentTimeMillis();
        String indexPath = "C:\\m\\my-java-code-repository\\lucene-demo\\my\\index";
        // 1. 指定索引库
        Directory directory = FSDirectory.open(new File(indexPath).toPath());

        // 2. 创建 IndexReader 对象
        IndexReader indexReader = DirectoryReader.open(directory);

        // 3. 创建 IndexSearcher 对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        SmartChineseAnalyzer standardAnalyzer = new SmartChineseAnalyzer();
        QueryParser parser = new QueryParser("content", standardAnalyzer);
        parser.setDefaultOperator(QueryParser.Operator.AND);
        Query query = parser.parse("兮");

        // 5. 执行查询, 第一个参数是查询对象, 第二个参数是查询结果返回的最大值
        TopDocs search = indexSearcher.search(query, 108);

        System.out.println("查询结果条数：" + search.totalHits);
        long end = System.currentTimeMillis() - start;
        System.out.println("查询耗时: " + end);

        // 6. 遍历查询结果
        for (ScoreDoc scoreDoc : search.scoreDocs) {
            // 6.1 根据 id 获取 Document, scoreDoc.doc 属性就是 document 对象的 id
            Document doc = indexSearcher.doc(scoreDoc.doc);
            System.out.println("内容：" + doc.get("content"));
            System.out.println(JSON.toJSONString(doc));
        }

        // 7. 释放资源
        indexReader.close();
    }

}
